import java.util.ArrayList;

/**
 * The class contain the methods for calculate h-index and contemporary h-index.
 * 
 */
public class HIndex {
	private ArrayList<Publications> publics;
	private String author;
	private int year;

	/**
	 * Calculate the h-index of an author, in a particular year, having a list
	 * of publication. The String authorToSearch have to contain name and
	 * surname separated by space. The int yearToSearch must be <= at the
	 * current year.
	 * 
	 * @param aPublic
	 *            an ArrayList of Publications object.
	 * @param authorToSearch
	 *            the author
	 * @param yearToSearch
	 *            the year
	 * @return the h-index.
	 * 
	 */

	public int calcHIndex(ArrayList<Publications> aPublic,
			String authorToSearch, int yearToSearch) {
		publics = aPublic;
		author = authorToSearch;
		year = yearToSearch;
		ArrayList<Integer> temp = new ArrayList<Integer>();
		int pippo = 0;
		for (int i = 0; i < publics.size(); i++) {
			for (int k = 0; k < publics.get(i).getAuthors().size(); k++) {
				if (author.equalsIgnoreCase(publics.get(i).getAuthors().get(k)
						.getName())) {
					pippo = 0;
					for (int j = 0; j < publics.get(i).getCitY().size(); j++) {

						if (publics.get(i).getCitY().get(j).getYear() <= yearToSearch) {
							pippo += publics.get(i).getCitY().get(j).getnCite();
						}
					}
					temp.add(pippo);
				}
			}

		}
		int find = 0;
		int x = temp.size();
		while (find < x && x >= 0) {

			for (int i = 0; i < temp.size(); i++) {
				if (temp.get(i) >= x) {
					find++;
				}
			}
			if (find >= x || x == 0) {
				return x;
			} else {
				x--;
			}
			find = 0;
		}
		return 0;
	}

	/**
	 * Calculate the h-index of an author, in a particular year, having a list
	 * of publication whit isbn code. The String authorToSearch have to contain
	 * name and surname separated by space.The int yearToSearch must be <= at
	 * the current year.
	 * 
	 * @param aPublic
	 *            an ArrayList of Publications object.
	 * @param authorToSearch
	 *            the author
	 * @param yearToSearch
	 *            the year
	 * @return the h-index.
	 */
	public int calcHIndexWithIsbn(ArrayList<Publications> aPublic,
			String authorToSearch, int yearToSearch) {

		publics = aPublic;
		author = authorToSearch;
		year = yearToSearch;
		ArrayList<Integer> temp = new ArrayList<Integer>();
		int pippo = 0;
		for (int i = 0; i < publics.size(); i++) {
			for (int k = 0; k < publics.get(i).getAuthors().size(); k++) {
				if (author.equalsIgnoreCase(publics.get(i).getAuthors().get(k)
						.getName())) {
					if (publics.get(i).getIsbn() != null) {
						pippo = 0;
						for (int j = 0; j < publics.get(i).getCitY().size(); j++) {

							if (publics.get(i).getCitY().get(j).getYear() <= yearToSearch) {
								pippo += publics.get(i).getCitY().get(j)
										.getnCite();
							}
						}
						temp.add(pippo);
					}
				}
			}

		}
		int find = 0;
		int x = temp.size();
		while (find < x && x >= 0) {

			for (int i = 0; i < temp.size(); i++) {
				if (temp.get(i) >= x) {
					find++;
				}
			}
			if (find >= x || x == 0) {
				return x;
			} else {
				x--;
			}
			find = 0;
		}
		return 0;

	}

	/**
	 * Calculate the h-index of an author, in a particular year, having a list
	 * of publication whit issn code. The String authorToSearch have to contain
	 * name and surname separated by space.The int yearToSearch must be <= at
	 * the current year.
	 * 
	 * @param aPublic
	 *            an ArrayList of Publications object.
	 * @param authorToSearch
	 *            the author
	 * @param yearToSearch
	 *            the year
	 * @return the h-index.
	 */
	public int calcHIndexWithIssn(ArrayList<Publications> aPublic,
			String authorToSearch, int yearToSearch) {
		publics = aPublic;
		author = authorToSearch;
		year = yearToSearch;
		ArrayList<Integer> temp = new ArrayList<Integer>();
		int pippo = 0;
		for (int i = 0; i < publics.size(); i++) {
			for (int k = 0; k < publics.get(i).getAuthors().size(); k++) {
				if (author.equalsIgnoreCase(publics.get(i).getAuthors().get(k)
						.getName())) {
					if (publics.get(i).getIssn() != null) {
						pippo = 0;
						for (int j = 0; j < publics.get(i).getCitY().size(); j++) {

							if (publics.get(i).getCitY().get(j).getYear() <= yearToSearch) {
								pippo += publics.get(i).getCitY().get(j)
										.getnCite();
							}
						}
						temp.add(pippo);
					}
				}
			}

		}
		int find = 0;
		int x = temp.size();
		while (find < x && x >= 0) {

			for (int i = 0; i < temp.size(); i++) {
				if (temp.get(i) >= x) {
					find++;
				}
			}
			if (find >= x || x == 0) {
				return x;
			} else {
				x--;
			}
			find = 0;
		}
		return 0;

	}

	/**
	 * Calculate the contemporary h-index of an author, in a particular year,
	 * having a list of publication. The String authorToSearch have to contain
	 * name and surname separated by space.The int yearToSearch must be <= at
	 * the current year.
	 * 
	 * @param aPublic
	 *            an ArrayList of Publications object.
	 * @param authorToSearch
	 *            the author
	 * @param yearToSearch
	 *            the year
	 * @return the h-index.
	 */
	public int contemporaryHIndex(ArrayList<Publications> aPublic,
			String authorToSearch, int yearToSearch) {
		publics = aPublic;
		author = authorToSearch;
		year = yearToSearch;
		ArrayList<Double> temp = new ArrayList<Double>();
		ArrayList<Integer> tempAnno = new ArrayList<Integer>();
		int pippo;
		int anno;
		for (int i = 0; i < publics.size(); i++) {
			for (int k = 0; k < publics.get(i).getAuthors().size(); k++) {
				if (author.equalsIgnoreCase(publics.get(i).getAuthors().get(k)
						.getName())) {
					pippo = 0;
					anno = 0;
					for (int j = 0; j < publics.get(i).getCitY().size(); j++) {

						if (publics.get(i).getCitY().get(j).getYear() <= yearToSearch) {
							pippo += publics.get(i).getCitY().get(j).getnCite();
							anno = publics.get(i).getYear();

						}

					}
					temp.add(1.0 * pippo);
					tempAnno.add(anno);
				}
			}

		}
		for (int i = 0; i < temp.size(); i++) {
			double f = temp.get(i);
			temp.set(i, (4.0 / ((yearToSearch - tempAnno.get(i)) + 1)) * f);
		}
		int find = 0;
		int x = temp.size();
		while (find < x && x >= 0) {

			for (int i = 0; i < temp.size(); i++) {
				if (temp.get(i) >= x) {
					find++;
				}
			}
			if (find >= x || x == 0) {
				return x;
			} else {
				x--;
			}
			find = 0;
		}
		return 0;
	}

	/**
	 * Calculate the contemporary h-index of an author, in a particular year,
	 * having a list of publication whit a issn code. The String authorToSearch
	 * have to contain name and surname separated by space.The int yearToSearch
	 * must be <= at the current year.
	 * 
	 * @param aPublic
	 *            an ArrayList of Publications object.
	 * @param authorToSearch
	 *            the author
	 * @param yearToSearch
	 *            the year
	 * @return the h-index.
	 */
	public int contemporaryHIndexWithIssn(ArrayList<Publications> aPublic,
			String authorToSearch, int yearToSearch) {
		publics = aPublic;
		author = authorToSearch;
		year = yearToSearch;
		ArrayList<Double> temp = new ArrayList<Double>();
		ArrayList<Integer> tempAnno = new ArrayList<Integer>();
		int pippo;
		int anno;
		for (int i = 0; i < publics.size(); i++) {
			for (int k = 0; k < publics.get(i).getAuthors().size(); k++) {
				if (author.equalsIgnoreCase(publics.get(i).getAuthors().get(k)
						.getName())) {
					if (publics.get(i).getIssn() != null) {
						pippo = 0;
						anno = 0;
						for (int j = 0; j < publics.get(i).getCitY().size(); j++) {

							if (publics.get(i).getCitY().get(j).getYear() <= yearToSearch) {
								pippo += publics.get(i).getCitY().get(j)
										.getnCite();
								anno = publics.get(i).getYear();

							}

						}
						temp.add(1.0 * pippo);
						tempAnno.add(anno);
					}
				}
			}

		}
		for (int i = 0; i < temp.size(); i++) {
			double f = temp.get(i);
			temp.set(i, (4.0 / ((yearToSearch - tempAnno.get(i)) + 1)) * f);
		}
		int find = 0;
		int x = temp.size();
		while (find < x && x >= 0) {

			for (int i = 0; i < temp.size(); i++) {
				if (temp.get(i) >= x) {
					find++;
				}
			}
			if (find >= x || x == 0) {
				return x;
			} else {
				x--;
			}
			find = 0;
		}
		return 0;
	}

	/**
	 * Calculate the contemporary h-index of an author, in a particular year,
	 * having a list of publication whit a isbn code. The String authorToSearch
	 * have to contain name and surname separated by space.The int yearToSearch
	 * must be <= at the current year.
	 * 
	 * @param aPublic
	 *            an ArrayList of Publications object.
	 * @param authorToSearch
	 *            the author
	 * @param yearToSearch
	 *            the year
	 * @return the h-index.
	 */
	public int contemporaryHIndexWithIsbn(ArrayList<Publications> aPublic,
			String authorToSearch, int yearToSearch) {
		publics = aPublic;
		author = authorToSearch;
		year = yearToSearch;
		ArrayList<Double> temp = new ArrayList<Double>();
		ArrayList<Integer> tempAnno = new ArrayList<Integer>();
		int pippo;
		int anno;
		for (int i = 0; i < publics.size(); i++) {
			for (int k = 0; k < publics.get(i).getAuthors().size(); k++) {
				if (author.equalsIgnoreCase(publics.get(i).getAuthors().get(k)
						.getName())) {
					if (publics.get(i).getIsbn() != null) {
						pippo = 0;
						anno = 0;
						for (int j = 0; j < publics.get(i).getCitY().size(); j++) {

							if (publics.get(i).getCitY().get(j).getYear() <= yearToSearch) {
								pippo += publics.get(i).getCitY().get(j)
										.getnCite();
								anno = publics.get(i).getYear();

							}

						}
						temp.add(1.0 * pippo);
						tempAnno.add(anno);
					}
				}
			}

		}
		for (int i = 0; i < temp.size(); i++) {
			double f = temp.get(i);
			temp.set(i, (4.0 / ((yearToSearch - tempAnno.get(i)) + 1)) * f);
		}
		int find = 0;
		int x = temp.size();
		while (find < x && x >= 0) {

			for (int i = 0; i < temp.size(); i++) {
				if (temp.get(i) >= x) {
					find++;
				}
			}
			if (find >= x || x == 0) {
				return x;
			} else {
				x--;
			}
			find = 0;
		}
		return 0;
	}

	/**
	 * 
	 * @return the year insert for the research
	 */
	public int getYear() {
		return year;
	}

	/**
	 * @return the author insert for the research
	 */
	public String getAuthorToSearch() {
		return author;
	}
}
